package com.ccl.iot.publics;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.RectF;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

import com.ccl.iot.template.GraphicView;

public class ImagePreviewView extends GraphicView {
	private Paint iPaint = new Paint();
	private Rect iRect = new Rect();
	
	private boolean iSelectRectVisible = false;
	
	private Bitmap iImage = null;
	private Rect iImageRect = null;
	
	private RectF iSelectRect = null;
	private Rect iDrawRect = null;
	
	public ImagePreviewView(Context aContext) {
		super(aContext);
		
		iPaint.setStyle(Style.STROKE);
		iPaint.setColor(Color.RED);
	}
	
	public void setSelectRectVisible(boolean aVisible){
		if (iSelectRectVisible != aVisible){
			iSelectRectVisible = aVisible;
			super.postInvalidate();
		}
	}
	
	private void updateDrawArea(){
		if (iRect != null && iImageRect != null && iRect.right > 0 && iRect.bottom > 0 && iImageRect.right > 0 && iImageRect.bottom > 0){
			float tViewScale = (float)iRect.right / (float)iRect.bottom;
			float tBmpScale = (float)iImageRect.right / (float)iImageRect.bottom;
			int tLeft, tTop, tRight, tBottom;
			
			if (tViewScale < tBmpScale){
				tLeft = 0;
				tRight = iRect.right;
				tBottom = (int) (iImageRect.bottom * ((float)iRect.right / (float)iImageRect.right));
				tTop = (iRect.bottom - tBottom) / 2;
				tBottom += tTop;
			}else{
				tTop = 0;
				tBottom = iRect.bottom;
				tRight = (int) (iImageRect.right * ((float)iRect.bottom / (float)iImageRect.bottom));
				tLeft = (iRect.right - tRight) / 2;
				tRight += tLeft;
			}
			
			if (iDrawRect == null){
				iDrawRect = new Rect(tLeft, tTop, tRight, tBottom);
			}else{
				iDrawRect.set(tLeft, tTop, tRight, tBottom);
			}
		}else{
			iDrawRect = null;
		}
		
		super.postInvalidate();
	}
	
	public Bitmap getImageBitmap(){
		return iImage;
	}
	
	public void setImageBitmap(Bitmap aBitmap) {
		if (iImage != null){
//			iImage.recycle();
		}
		
		iImage = aBitmap;
		
		if (iImage != null){
			iImageRect = new Rect(0, 0, iImage.getWidth(), iImage.getHeight());
		}else{
			iImageRect = null;
		}
		
		updateDrawArea();
		
		super.postInvalidate();
	}
	
	@Override
	public void surfaceChanged(SurfaceHolder aHolder, int aFormat, int aWidth, int aHeight) {
		super.surfaceChanged(aHolder, aFormat, aWidth, aHeight);;
		
		if (iRect == null){
			iRect = new Rect(0, 0, aWidth, aHeight);
		}else{
			iRect.set(0, 0, aWidth, aHeight);
		}
		
		updateDrawArea();
	}
	
	private TouchResolver iTouchResolver = new TouchResolver(1){
		@Override
		public void onTouchMove(float aSrcX, float aSrcY, float aDstX, float aDstY) {
			if (iDrawRect != null){
				int tOffsetX = (int)(aDstX - aSrcX);
				int tOffsetY = (int)(aDstY - aSrcY);
				
				iDrawRect.offset(tOffsetX, tOffsetY);
				
				ImagePreviewView.this.postInvalidate();
			}
		}
		
		@Override
		public void onSelectRectChange(RectF aSrc, RectF aDst) {
			if (iDrawRect != null && aSrc != null && aDst != null){				
				float tSrcWidth = aSrc.width();
				float tSrcHeight = aSrc.height();
				float tDstWidth = aDst.width();
				float tDstHeight = aDst.height();
				double tD1 = Math.sqrt((tSrcWidth * tSrcWidth) + (tSrcHeight * tSrcHeight));
				double tD2 = Math.sqrt((tDstWidth * tDstWidth) +(tDstHeight * tDstHeight));
				float tScale = (float) (tD2 / tD1);
				int tScaleWidth = (int) (iDrawRect.width() * tScale);
				int tScaleHeight = (int) (iDrawRect.height() * tScale);
				int tScaleX, tScaleY;
				Rect tRect;
				
				tRect = new Rect(iDrawRect);
								
				if (tScale > 1){	//Zoom in
					tScaleX = (int) ((tScaleWidth - iDrawRect.width()) / 2f);
					tScaleY = (int) ((tScaleHeight - iDrawRect.height()) / 2f);
					
					iDrawRect.left -= tScaleX;
					iDrawRect.right = iDrawRect.left + tScaleWidth;
					iDrawRect.top -= tScaleY ;
					iDrawRect.bottom = iDrawRect.top + tScaleHeight;
					
				}else if (tScale < 1){	//Zoom out
					tScaleX = (int) ((iDrawRect.width() - tScaleWidth) / 2f);
					tScaleY = (int) ((iDrawRect.height() - tScaleHeight) / 2f);
					
					iDrawRect.left += tScaleX;
					iDrawRect.right = iDrawRect.left + tScaleWidth;
					iDrawRect.top += tScaleY;
					iDrawRect.bottom = iDrawRect.top + tScaleHeight;
				}else{
					float tSrcCenterX = aSrc.centerX(), tSrcCenterY = aSrc.centerY();
					float tDstCenterX = aDst.centerX(), tDstCenterY = aDst.centerY();
					int tOffsetX = (int)(tDstCenterX - tSrcCenterX);
					int tOffsetY = (int)(tDstCenterY - tSrcCenterY);
					
					iDrawRect.offset(tOffsetX, tOffsetY);
				}
				
				if (tScale < 1){
					if (iDrawRect.width() < iRect.width() && iDrawRect.height() < iRect.height()){
						iDrawRect.set(tRect);
					}
				}else if (tScale > 1){
					if (iDrawRect.width() > iImageRect.width() * 10){
						iDrawRect.set(tRect);
					}
				}
				
				iSelectRect = new RectF(aDst);
				
				ImagePreviewView.this.postInvalidate();
			}
		}

		@Override
		public void onTouchCancel() {
			if (iDrawRect != null){
				int tLeft = 0, tTop = 0;
				iSelectRect = null;
				
				if (iDrawRect.width() >= iRect.width()){
					if (iDrawRect.left < 0){
						tLeft = iDrawRect.left;
						
						if (iDrawRect.right < iRect.right){
							tLeft += (iRect.right - iDrawRect.right);
						}
					}
				}else{
					tLeft = (iRect.width() - iDrawRect.width()) >> 1;
				}
				
				if (iDrawRect.height() >= iRect.height()){
					if (iDrawRect.top< 0){
						tTop = iDrawRect.top;
						
						if (iDrawRect.bottom < iRect.bottom){
							tTop += (iRect.bottom - iDrawRect.bottom);
						}
					}
				}else{
					tTop = (iRect.height() - iDrawRect.height()) >> 1;
				}
				
				if (tLeft != iDrawRect.left || tTop != iDrawRect.top){
					iDrawRect.offsetTo(tLeft, tTop);
				}
				
				ImagePreviewView.this.postInvalidate();
			}
		}
	};
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		return iTouchResolver.onTouchEvent(event);
	}
	
	@Override
	protected void onPaint(Canvas aCanvas) {
		super.onPaint(aCanvas);
		
		if (aCanvas != null && iImage != null && iImageRect != null && iDrawRect != null){
			final RectF tRect = iSelectRect;
			aCanvas.drawColor(Color.BLACK);
			
			aCanvas.drawBitmap(iImage, iImageRect, iDrawRect, iPaint);
			
			if (iSelectRectVisible && tRect != null){
				aCanvas.drawRect(tRect, iPaint);
			}
			
			aCanvas.drawRect(iDrawRect, iPaint);
		}
	}
	
	public Bitmap getImageSnapshot(){
		if (iImage != null && iRect != null && iDrawRect != null){
			int tWidth = iRect.width();
			int tHeight = iRect.height();
			int tDrawWidth = iDrawRect.width();
			int tDrawHeight = iDrawRect.height();
			
			if (tWidth > 0 && tHeight > 0 && tDrawWidth > 0 && tDrawHeight > 0){
				int tImageWidth, tImageHeight;
				Rect tDrawRect = new Rect(iDrawRect);
				Bitmap tImage;
				Canvas tCanvas;
				
				if (tDrawWidth < tWidth || tDrawHeight < tHeight){
					tImageWidth = tDrawWidth;
					tImageHeight = tDrawHeight;
					
					tDrawRect.offset((tDrawWidth - tWidth) >> 1, (tDrawHeight - tHeight) >> 1);
				}else{
					tImageWidth = tWidth;
					tImageHeight = tHeight;
				}
				
				tImage = Bitmap.createBitmap(tImageWidth, tImageHeight, Config.RGB_565);
				tCanvas = new Canvas(tImage);
				
				tCanvas.drawBitmap(iImage, iImageRect, tDrawRect, iPaint);
//				tCanvas.save();
//				tCanvas.restore();
				
				return tImage;
			}
		}
		
		return null;
	}
}
